from PIL import Image
imagen = Image.open('Portada_2do_avance_PIA1.jpg')
imagen
import pandas as pd
import numpy as np
import json
df = pd.read_csv("pah_wikp_combo.csv", header=0, index_col=0, parse_dates=True, squeeze=True)
El csv. lo puse en la carpeta 7mo. Semestre, Mineria de datos, Etapa 3
df = pd.read_csv("pah_wikp_combo.csv",encoding='utf8')
df.shape
En nuestra base de datos tenemos 11 columnas, con 695 renglones.
df.head()
Nos muestras los datos de los "primeros" 5 renglones
df.tail()
Nos muestras los datos de los "ultimos" 5 renglones
df.columns
df.columns = ['Fecha','Ciudad','Estado','Latitud','Longitud','Tipo_de_área','Escuela','Muertes','Heridos','True','Wikp_o_Pah']
df.columns
df
En este caso no cambie el nombre de las columnas lo unico que hice fue traducirlas
df.dtypes
Tipo de dato que contiene cada columna
df['Heridos'].fillna(0,inplace=True)
Convierto los NaN de la Columna Heridos a 0
df['True'].fillna(0,inplace=True)
Convierto los NaN de la columna True a cero
df
Fecha: Nos da la fecha por año-mes-día Ciudad: Nos menciona alguna ciudad del estado donde ocurrio el tiroteo Estado: Menciona uno de los 52 estados donde ocurrio el tiroteo Latitud y Longitud: Describen en que coordenada geografica ocurrio el tiroteo Tipo_de_área: Menciona urban=urbano, suburban=suburbano, 0=otro Escuela: C=universidad, HS=escuela secundaria, MS=escuela intermedia, ES=escuela primaria, -=desconocido Muertes: Cuantas personas fallecieron Heridos:Cuantas personas resultaron heridas True:Si solo ocurrio muertes y ningun herido Wikp_o_Pah: Pah:solo ocurrio muertes, Wikp:ocurrio muerte y heridos
df.Escuela.unique()
Nos menciona las tipos de clases que estan en la columna Escuela
Escuelas_vs_fecha = df.loc[df.Escuela == 'C'].Fecha
Escuelas_vs_fecha
Nos dice cuantas veces ocurrio un tiroteo en C=Universidad, ademas de darnos la fecha cuando ocurrio
df.isnull()
Aqui podemos ver que tenemos datos nulos en el "Tipo de área" por lo que debemos de corregir eso como lo hice anteriormente
df.isnull().any()
Me marca que tengo NaN en la columna "Tipo de área" y "Escuela" aunque en "Escuela" esta todo bien :s, no hay NaN
df['Tipo_de_área'].fillna(0,inplace=True)
Esta corregido la columna de "Tipo de área" quitando los NaN a cero
df['Total victimas']=df.loc[df['Muertes']>=0, ['Muertes','Heridos']].sum(axis=1)
df
Agregue la columna de Total de víctimas para poder hacer el gráfico de USA, solo sume la columna de Muertes y Heridos para obtener el total de personas que fueron victimas del tiroteo.
PREGUNTAS DE INTERES:
¿Para que me puede servir estas agrupaciones para la práctica siguiente? Me pueden servir para poder realizar graficas, en mi caso escogimos la columna de las escuelas de la universidad, por lo que al seleccionarla podemos realizar graficas, ¿como cuando ocurrieron tiroteos?, ademas de sus fechas correspondientes. Tambien podemos hacer una serie de tiempo, por lo que podemos utilizar la técnica de la predicción para saber cuantas personas pueden morir o el porcentaje de mortalidad que tiene los tiroteos en las universidades.
df['Muertes'].sum()
En nuestra base de datos, desde 1990 a 2020 han muertos 806 personas a causa de los tiroteos en EUA
df['Muertes'].mean()
1 persona a muerto por promedio desde 1990 a 2020, a causa de los tiroteos en EUA
df['Heridos'].cumsum()
Tenemos un total de 609 heridos a causa de los tiroteos
df['Muertes'].min()
El menor número de personas que han muerto en un tiroteo es de saldo blanco
df['Muertes'].max()
El mayor número de personas que han muerto en un tiroteo es de 33 personas
df['Muertes'].median()
df['Muertes'].var()
df['Muertes'].std()
df.corr()
df.cov()
Al tener la correlación números muy cercanos a 1 y al ser la covarianza números grandes podemos concluir que existe una relación lineal muy grande entre el número de "muertes", el Total de vicitmas y el número de "heridos" en los tiroteos.
import seaborn as sns
import matplotlib.pyplot as plt
import pylab as pl
df.plot(x='Fecha',y='Total victimas',figsize=(15,5))
df.Fecha=pd.to_datetime(df.Fecha)
df.set_index('Fecha')
plt.title('Serie de Tiempo de Tiroteos',color='black')
plt.tight_layout()
plt.xlabel("Fecha de los tiroteos")
plt.ylabel("Total de victimas")
plt._show()
NOTA: figsize=(valor x,valor y) df.Fecha=pd.to_datetime(df.Fecha) df.set_index('Fecha') df['Total victimas'].plot()
Como "Serie de Tiempo" usamos como variable x="Fecha" y como variable y="Total victimas".
Como nuestra gráfica es muy grande solo tomamos del año de 2016 a 2020 y a simple vista se ve que no sigue una tendencia, .*.La serie es Estacionaria en Media
from statsmodels.tsa.stattools import adfuller
X = df['Total victimas'].values
result = adfuller(X)
print('ADF Statistic: %f' % result[0])
print('p-value: %f' % result[1])
print('Critical Values:')
for key, value in result[4].items():
print('\t%s: %.3f' % (key, value))
Prueba de Dickey Fuller Aumentada (Varianza), H0:La serie es no Estacionaria vs H1:La serie es Estacionaria, con un p-valor:0.00(muy pequeño)<alfa, .*.la serie es ESTACIONARIA en Varianza
.*. La serie de Tiempo "Tiroteos en EUA de 1990-2020" es una serie ESTACIONARIA por la media y varianza
Estado=df['Estado']
Muertes=df['Muertes']
Heridos=df['Heridos']
RL = pd.DataFrame({'Estado': Estado, 'Muertes': Muertes, 'Heridos': Heridos})
RL.head(690)
1.-Es representar los datos para poder intuir si existe una relación y cuantificar dicha relación mediante un coeficiente de correlación.
fig, ax = plt.subplots(figsize=(15, 6))
RL.plot(
x = 'Muertes',
y = 'Heridos',
c = 'firebrick',
kind = "scatter",
ax = ax
)
ax.set_title('Distribución de Muertes y Heridos');
Esta grafica nos muestra que el número de "Heridos" y el número de "Muertes estan relacionados. Esto significa que entre menos heridos tengamos menos cantidad de muertes sucedera en un tiroteo escolar de EUA.
df_Prediccion = pd.read_csv("pah_wikp_combo_Prediccion.csv", header=0, index_col=0, parse_dates=True, squeeze=True)
df_Prediccion.plot(x='FechaVF',y='Predicción',figsize=(15,5))
df.Fecha=pd.to_datetime(df.Fecha)
df.set_index('Fecha')
plt.title('Predicción de Tiroteos 2021-2025',color='black')
plt.tight_layout()
plt.xlabel("Fecha de los tiroteos")
plt.ylabel("Total de victimas")
plt._show()
Usando "EXCEL" obtuve las predicciones para el año de 2021 a 2025.
import plotly.graph_objects as go
import pandas as pd
df['Resumen'] ='Ciudad: ' + df['Ciudad'] + ', ' + 'Estado: ' + df['Estado'].astype(str)
fig = go.Figure(data=go.Scattergeo(
lon = df['Longitud'],
lat = df['Latitud'],
text = df['Resumen'],
mode = 'markers',
marker_color = df['Total victimas'],
))
fig.update_layout(
title = 'Tiroteos en EUA desde 1990-2020<br>(Coloque el cursor sobre el estado)',
geo_scope='usa',
)
fig.show()
Mapa de los Estados Unidos con Alaska, que cada punto representa la ubicación del estado donde se llevo a cabo un tiroteo desde el año de 1990-2020 Mapa de Estados Unidos
Agrego una columna nueva llamada "Resumen" la cual me dara la Latitud, Longitud, Ciudad y Estado, para que cuando yo solo de click en algun punto me muestre toda esa información.
df['Resumen1'] ='Ciudad: ' + df['Ciudad'] + ', ' + 'Estado: ' + df['Estado'] + ', ' + 'Total de victimas: ' + df['Total victimas'].astype(str)
fig = go.Figure(data=go.Scattergeo(
locationmode = 'USA-states',
lon = df['Longitud'],
lat = df['Latitud'],
text = df['Resumen1'],
mode = 'markers',
marker = dict(
size = 8,
opacity = 0.8,
reversescale = True,
autocolorscale = False,
symbol = 'square',
line = dict(
width=1,
color='rgba(102, 102, 102)'
),
colorscale = 'Blues',
cmin = 0,
color = df['Total victimas'],
cmax = df['Total victimas'].max(),
colorbar_title="Total de victimas<br>1990-2020"
)))
fig.update_layout(
title = 'Tiroteos en EUA desde 1990-2020<br>(Coloque el cursor sobre el estado)',
geo = dict(
scope='usa',
projection_type='albers usa',
showland = True,
landcolor = "rgb(250, 250, 250)",
subunitcolor = "rgb(217, 217, 217)",
countrycolor = "rgb(217, 217, 217)",
countrywidth = 0.5,
subunitwidth = 0.5
),
)
fig.show()
Mapa de los Estados Unidos con Alaska, que cada punto representa la ubicación del estado donde se llevo a cabo un tiroteo, ademas de las victimas que resultaron afectadas desde 1990-2020
import plotly.express as px
Tiroteos_estados=df.Estado.value_counts().head(12).reset_index()
Tiroteos_estados.columns=['Estado','Total victimas']
figE = px.bar(Tiroteos_estados, x="Total victimas", y="Estado", orientation='h',color='Estado')
figE.show()
Nos presentan los primeros 12 estados, de los cuales al hacer click en cualquiera de ellos nos muestra el Total de victimas(a causa del tiroteo) que a llegado a tener dicho estado desde 1990-2020
Tiroteos_ciudades=df.Ciudad.value_counts().head(15).reset_index()
Tiroteos_ciudades.columns=['Ciudad','Total victimas']
figC = px.bar(Tiroteos_ciudades, x="Total victimas", y="Ciudad", orientation='h',color='Ciudad')
figC.show()
Nos presentan las primeras 15 ciudades, de los cuales al hacer click en cualquiera de ellas nos muestra el Total de victimas(a causa del tiroteo) que a llegado a tener dicha ciudad desde 1990-2020
import pandas as pd
from matplotlib.pyplot import pie, axis, show
%matplotlib inline
sums = df.groupby(df["Estado"])["Total victimas"].sum().head(12)
axis('equal');
pie(sums, labels=sums.index);
show()
Decidimos utilizar la gráfica de pastel ya que nos ayuda a entender, el Total de víctimas que tiene cada estado a causas de los tiroteos, solo mostre 15 estados ya que al poner todos, la gráfica no es entendible.
sums = df.groupby(df["Ciudad"])["Total victimas"].sum().head(15)
axis('equal');
pie(sums, labels=sums.index);
show()
Mismo caso, solo que en vez de "Estados" maneje las "Ciudades", al igual solo mostre solo 15 ciudades, por que si hubiera puesto todas las ciudades no se entenderia bien el grafico.
Heridos_escuela_primaria=df[(df['Heridos']>=1)&(df['Escuela']=='ES')]
totalHES=len(Heridos_escuela_primaria)
Muertes_escuela_primaria=df[(df['Muertes']>=1)&(df['Escuela']=='ES')]
totalMES=len(Muertes_escuela_primaria)
Heridos_escuela_intermedia=df[(df['Heridos']>=1)&(df['Escuela']=='MS')]
totalHMS=len(Heridos_escuela_intermedia)
Muertes_escuela_intermedia=df[(df['Muertes']>=1)&(df['Escuela']=='MS')]
totalMMS=len(Muertes_escuela_intermedia)
Heridos_escuela_secundaria=df[(df['Heridos']>=1)&(df['Escuela']=='HS')]
totalHHS=len(Heridos_escuela_secundaria)
Muertes_escuela_secundaria=df[(df['Muertes']>=1)&(df['Escuela']=='HS')]
totalMHS=len(Muertes_escuela_secundaria)
Heridos_universidad=df[(df['Heridos']>=1)&(df['Escuela']=='C')]
totalHC=len(Heridos_universidad)
Muertes_universidad=df[(df['Muertes']>=1)&(df['Escuela']=='C')]
totalMC=len(Muertes_universidad)
Escuelas=['Escuela Primaria','Escuela intermedia','Secundaria-Preparatoria','Universidad']
fig = go.Figure()
fig.add_trace(go.Bar(x=Escuelas, y=[totalHES,totalHMS,totalHHS,totalHC],
base=0,
marker_color='blue',
name='Heridos'))
fig.add_trace(go.Bar(x=Escuelas, y=[totalMES,totalMMS,totalMHS,totalMC],
base=0,
marker_color='red',
name='Muertes'
))
fig.update_layout(title_text='Tiroteos por nivel académico')
fig.show()
Enfocandonos en la Escuela, se realizó una tabla comparando los 4 niveles educativos respecto a las Muertes y Heridos, que han ocurrido desde 1990 a 2020, dandonos entender que han ocurrido más tiroteos en las escuelas secundaria-preparatoria.
df['Año'] = pd.DatetimeIndex(df['Fecha']).year
Tiroteos_anuales=df.Año.value_counts().reset_index()
Tiroteos_anuales.columns=['Año','Total victimas']
fig = px.scatter(Tiroteos_anuales, x="Año", y="Total victimas", size="Total victimas", color="Total victimas",
hover_name="Total victimas", log_x=True, size_max=60)
fig.show()
Utilizando un grafico de calor, se comparo el Total de victimas vs Año, el total de victimas es grande si el color es claro e inversamente proporcional si el color es más fuerte entonces el total de victimas es más pequeño.
import seaborn as sns
import matplotlib.pyplot as plt
df.head()
sns.pairplot(df[['Muertes', 'Heridos','Total victimas','Año']])
Se realizó el siguiente grafico de dispersión para ver si es que siguen un comportamiento, como se puede ver las "Muertes" con el número de "Heridos" esta muy relacionado.
sns.lmplot(x='Muertes', y='Heridos', hue='Wikp_o_Pah',
data=df.loc[df['Wikp_o_Pah'].isin(['Wikp', 'Pah'])],
fit_reg=False)
Decidí tomar el Wikp_o_Pah, ya que me llamó la atención ver como ambas chocan y ocurre un Pah:solo ocurrio muertes o un Wikp:ocurrio muerte y heridos.
sns.lmplot(x='Muertes', y='Heridos', hue='Escuela',
data=df.loc[df['Escuela'].isin(['C', 'HS','MS','ES','-'])],
fit_reg=False)
En esta gráfica multivariante decidi tomar la Escuela, ya que me interesa saber a que nivel educativo suelen haber mas "Muertes" y "Heridos a causa del tiroteo en EUA, por lo que la Escuela se divide en: C=universidad, HS=escuela secundaria, MS=escuela intermedia, ES=escuela primaria, -=desconocido
f,ax=plt.subplots(figsize = (9,9))
sns.heatmap(df.corr(),annot= True,linewidths=0.5,fmt = ".1f",ax=ax)
plt.xticks(rotation=90)
plt.yticks(rotation=0)
plt.title('Mapa de correlación')
plt.savefig('graph.png')
plt.show()
Criterio de Cohen (1998), nos dice que entre: 0.1-0.3 efecto pequeño, 0.3-0.5 efecto mediano y >=0.5 efecto grande
Como podemos observar la correlación es muy buena para Muertes-Heridos, Muertes-Total victimas, Heridos-Total victimas. Sin embargo nosotros usamos Año-Total victimas, ya que nos interesa saber como se comporta esta serie de tiempo, a simple vista se ve que tienen una correlación muy pequeña 0.1 eso nos quiere decir que tiene una débil tendencia o habra mas dispersión en la nube de puntos
W = plt.hist(df[df["Wikp_o_Pah"] == "Wikp"].Muertes,bins=30,fc = (1,0,0,0.5),label = "Wikp",orientation='horizontal')
P = plt.hist(df[df["Wikp_o_Pah"] == "Pah"].Muertes,bins=30,fc = (0,1,0,0.5),label = "Pah",orientation='horizontal')
plt.legend()
plt.xlabel("Frecuencia")
plt.ylabel("Número de muertos")
plt.title("Histograma")
plt.show()
W = plt.hist(df[df["Wikp_o_Pah"] == "Wikp"].Heridos,bins=30,fc = (1,0,0,0.5),label = "Wikp",orientation='horizontal')
P = plt.hist(df[df["Wikp_o_Pah"] == "Pah"].Heridos,bins=30,fc = (0,1,0,0.5),label = "Pah",orientation='horizontal')
plt.legend()
plt.xlabel("Frecuencia")
plt.ylabel("Número de heridos")
plt.title("Histograma")
plt.show()
Utilice la columna "Wikp o Pah" vs Muertes-Heridos, ya que nos interesa saber con que Frecuencia suelen ocurrir, Pah:solo ocurrio muertes, Wikp:ocurrio muerte y heridos
Dada nuestra base de datos modificada pudimos comprender que varios de nuestros objetivos se pueden cumplir.
Como primer punto nuestro objetivo principal es determinar el impacto, que el tiroteo en las escuelas pueda llegar a generar en el futuro de EUA se pudo ver gracias a la gráfica de serie de tiempo la cual nos muestra los años vs total de víctimas ya que con ayuda de la estadística pudimos realizar diversas pruebas para poder obtener las predicciones, para los años de 2021-2025, sin embargo al tener una correlación muy pequeña entre los años y el total de víctimas esto hace que tengamos una débil tendencia o haya más dispersión en la nube de puntos. Lo cual significa que debemos de encontrar otras pruebas para obtener mejores predicciones y así poder ver el comportamiento que llegaran a tener los tiroteos en las escuelas de EUA.
Finalmente, nuestro objetivo secundario se cumplió, por que la gráfica del mapa de EUA nos muestra los Estados donde han ocurrido los tiroteos, además de apoyarnos con la gráfica de barras de Total de víctimas vs Estado y Total de víctimas vs Ciudad. Esto lo podemos mejorar mas investigando de manera descriptiva el por que esos estados o ciudad suelen ocurrir más tiroteos.
import pandas as pd
import numpy as np
import json
dfModificado = pd.read_csv("Pah_whikp_modificado.csv")
dfModificado.columns = ['Fecha','Ciudad','Estado','Latitud','Longitud','Tipo_de_área','Escuela','Muertes','Heridos','True','Wikp_o_Pah','Descripción']
dfModificado0= dfModificado.fillna(0)
dfModificado0['Total victimas']=dfModificado0.loc[dfModificado0['Muertes']>=0, ['Muertes','Heridos']].sum(axis=1)
dfModificado0.drop(['Descripción'], axis=1)
Pequeño experimento para ver el comportamiento, ya que antes de esta base de datos solo teniamos dos columnas con números enteros, ahora para las columnas "Tipo de área", "True" y "Wikp o Pah", de texto pasaron a datos númericos.
Tipo de area: otro tipo=0, subbarn=1, urban=2 Escuela: C=Universidad=1, HS=Escuela secundaria=2, MS=Escuela intermedia=3, ES=Escuela primaria=4, -=desconocido=5 TRUE: Falso=0, Verdadero=1 Wikp o Pah: Wikp=0, Pah=1
import seaborn as sns
import matplotlib.pyplot as plt
f,ax=plt.subplots(figsize = (15,15))
sns.heatmap(dfModificado0.corr(),annot= True,linewidths=0.5,fmt = ".1f",ax=ax)
plt.xticks(rotation=90)
plt.yticks(rotation=0)
plt.title('Mapa de correlación')
plt.savefig('graph.png')
plt.show()